package ai.assist.common.utils;

import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public class DateUtilsEx {

    private static final String sdf = "yyyy-MM-dd HH:mm:ss";
    private static final String sdf2 = "yyyyMMddHHmmss";

    private static final String sdfDay = "yyyy-MM-dd";

    public static String getStringDateTime(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sd = new SimpleDateFormat(sdf);
        return sd.format(date);
    }

    public static String getStringDateTime2(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sd = new SimpleDateFormat(sdf2);
        return sd.format(date);
    }
    public static String getStringDateFormat(Date date, String format) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sd = new SimpleDateFormat(format);
        return sd.format(date);
    }

    public static int getleftDay(Date date, Date limitDay) {
        long count = limitDay.getTime() - date.getTime();
        long left = count % 86400000;
        int days = (int) count / 86400000;
        if (count <= 0) {
            if (left != 0) {
                return days - 1;
            }
            return days;
        }
        if (left != 0) {
            return days + 1;
        }
        return days;
    }

//    public static void main(String[] args) {
//        Date date = new Date();
//        String limitDate = "2023-01-17 23:59:59";
//        Date limit = getDateTimeByString(limitDate);
//        System.out.println(getleftDay(date, limit));
//    }

    public static String getYear(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat sd = new SimpleDateFormat("yyyy");
        return sd.format(date);
    }

    /**
     * 时间转换
     *
     * @param day
     * @return
     */
    public static Date parseDayByDay(String day) {
        if (StringUtils.isEmpty(day)) {
            return null;
        }
        SimpleDateFormat fmt = new SimpleDateFormat(sdfDay);
        try {
            Date dayTime = fmt.parse(day);
            return dayTime;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date getDateTimeByString(String day) {
        if (StringUtils.isEmpty(day)) {
            return null;
        }
        SimpleDateFormat fmt = new SimpleDateFormat(sdf);
        try {
            Date dayTime = fmt.parse(day);
            return dayTime;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date getDateTimeByString2(String day) {
        if (StringUtils.isEmpty(day)) {
            return null;
        }
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        try {
            Date dayTime = fmt.parse(day);
            return dayTime;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 当天
     *
     * @return
     */
    public static DateDuration getToday() {
        LocalDate now = LocalDate.now();
        LocalDateTime dayStart = LocalDateTime.of(now, LocalTime.MIN);
        LocalDateTime dayEnd = LocalDateTime.of(now, LocalTime.MAX);
        return new DateDuration(dayStart, dayEnd);
    }

    /**
     * 本周
     *
     * @return
     */
    public static DateDuration getThisWeek() {
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH);
        int day = cal.get(Calendar.DAY_OF_MONTH);

        cal.set(year, month, day, 0, 0, 0);
        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());

        LocalDateTime weekStart = toLocalDateTime(cal);
        LocalDateTime weekEnd = weekStart.plusWeeks(1);

        return new DateDuration(weekStart, weekEnd);
    }


    public static LocalDateTime toLocalDateTime(Calendar calendar) {
        if (calendar == null) {
            return null;
        }

        TimeZone tz = calendar.getTimeZone();
        ZoneId zid = (tz != null ? tz.toZoneId() : ZoneId.systemDefault());

        return LocalDateTime.ofInstant(calendar.toInstant(), zid);
    }

    /**
     * 获取多少天后的日期
     *
     * @param day
     * @return
     */
    public static Date getDateByDay(Integer day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 24 * day);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date getMonthByDay(Integer month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, month);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取行为过期时间(去年的昨天0点)
     *
     * @return
     */
    public static Date getOvertimeStartDate() {
        Date date = new Date();// 取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, -1);// 把日期往后增加一年.整数往后推,负数往前移动
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取过期时间结束时间(去年今天0点)
     *
     * @return
     */
    public static Date getOvertimeEndDate() {
        Date date = new Date();// 取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, -1);// 把日期往后增加一年.整数往后推,负数往前移动
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取去年年初日期
     * @return
     */
    public static Date getLastYearStartDate() {
        Date date = new Date();// 取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, -1);// 把日期往后增加一年.整数往后推,负数往前移动
        calendar.set(Calendar.MONTH,1);
        calendar.set(Calendar.DAY_OF_MONTH,0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static String getDay(Date day) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        return fmt.format(day);
    }

    public static String getMonth(Date day) {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM");
        return fmt.format(day);
    }

    /**
     * 获取指定日期N天前后的日期时间
     *
     * @return Date 日期
     */
    public static Date getDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, 24 * day);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date dateToISODate(Date dateStr) {
        Date parse = null;
        try {
            // 解析字符串时间
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            parse = format.parse(format.format(dateStr));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return parse;
    }

    /**
     * 获取指定日期N天前后的日期时间
     *
     * @return Date 日期
     */
    public static Date getDayEnd(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, 24 * day);
        calendar.set(Calendar.HOUR, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    public static String getAddDayTimeString(Date date, int addDay, int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, 24 * addDay);
        calendar.set(Calendar.HOUR, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, second);
        SimpleDateFormat sd = new SimpleDateFormat(sdf);
        return sd.format(calendar.getTime());
    }

    public static Date getAddYearTime(Date date, int addYear) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, addYear);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date getDayTime(Date date, int hour, int minute, int second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        calendar.add(Calendar.MINUTE, minute);
        calendar.add(Calendar.SECOND, second);
        return calendar.getTime();
    }

    public static String getDayEndString(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        SimpleDateFormat fmt = new SimpleDateFormat(sdf);
        return fmt.format(calendar.getTime());
    }

//    public static Date getMonth(Date date, int month) {
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(date);
//        calendar.add(Calendar.MONTH,month);
//        calendar.set(Calendar.MINUTE, 0);
//        calendar.set(Calendar.SECOND, 0);
//        return calendar.getTime();
//    }

    /**
     * 获取指定日期N月前后第一天日期
     *
     * @param date
     * @param month
     * @return
     */
    public static Date getMonthDay(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date getMonth(Date date, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, month);
        return calendar.getTime();
    }

    public static int countMonths(Date date1, Date date2) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        c1.setTime(date1);
        c2.setTime(date2);
        int year = c2.get(Calendar.YEAR) - c1.get(Calendar.YEAR);
//开始日期若小月结束日期
        if (year < 0) {
            year = -year;
            return year * 12 + c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
        }
        return year * 12 + c2.get(Calendar.MONTH) - c1.get(Calendar.MONTH);
    }


    public static Date getDayStart(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date getMonthStart(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    public static Date getMonthEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH,  calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }


//    /**
//     * 默认开始时间 上一个月26号
//     * @param month
//     * @return
//     */
//    public static Date getMonth25Day(Integer month) {
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(new Date());
//        calendar.add(Calendar.MONTH, month);
//        calendar.set(Calendar.DAY_OF_MONTH, 26);
//        calendar.set(Calendar.HOUR_OF_DAY, 0);
//        calendar.set(Calendar.MINUTE, 0);
//        calendar.set(Calendar.SECOND, 0);
//        return calendar.getTime();
//    }

//    /**
//     * 默认开始时间 上一个月26号
//     * @param date
//     * @return
//     */
//    public static Date getDefaultStart(Date date) {
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(date);
//        calendar.add(Calendar.MONTH, -1);
//        calendar.set(Calendar.DAY_OF_MONTH, 26);
//        calendar.set(Calendar.HOUR_OF_DAY, 0);
//        calendar.set(Calendar.MINUTE, 0);
//        calendar.set(Calendar.SECOND, 0);
//        return calendar.getTime();
//    }
//
//    /**
//     * 默认结束时间 本月25号结束
//     * @param date
//     * @return
//     */
//    public static Date getDefaultEnd(Date date) {
//        Calendar calendar = Calendar.getInstance();
//        calendar.setTime(date);
//        calendar.set(Calendar.DAY_OF_MONTH, 26);
//        calendar.set(Calendar.HOUR_OF_DAY, 0);
//        calendar.set(Calendar.MINUTE, 0);
//        calendar.set(Calendar.SECOND, 0);
//        return calendar.getTime();
//    }


    public static Date getYearDate(Integer addYear) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.YEAR, addYear);
        return calendar.getTime();
    }

    public static Date getDayEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }


}
